﻿/*
 * copyright (c) 2009 hvbird
 *
 * This file is part of tdlib.
 *
 * tdlib is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * tdlib is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

namespace TDLib.ImageTools
{
    public class ImgScale
    {
        /// <summary>
        /// 缩小图片，不保持比例，原图片缩放后充满整个尺寸
        /// </summary>
        /// <param name="strOldPic">源图文件名(包括路径)</param>
        /// <param name="strNewPic">缩小后保存为文件名(包括路径)</param>
        /// <param name="intWidth">缩小至宽度</param>
        /// <param name="intHeight">缩小至高度</param>
        public void SmallPic(string strOldPic, string strNewPic, int intWidth, int intHeight)
        {

            System.Drawing.Bitmap objPic, objNewPic;
            try
            {
                objPic = new Bitmap(strOldPic);
                objNewPic = new Bitmap(objPic, intWidth, intHeight);
                saveImg(objNewPic, strNewPic);
            }
            catch (Exception exp) { throw exp; }
            finally
            {
                objPic = null;
                objNewPic = null;
            }
        }

        /// <summary>
        /// 按比例缩小图片，自动计算高度
        /// </summary>
        /// <param name="strOldPic">源图文件名(包括路径)</param>
        /// <param name="strNewPic">缩小后保存为文件名(包括路径)</param>
        /// <param name="intWidth">缩小至宽度</param>
        public void SmallPicW(string strOldPic, string strNewPic, int intWidth)
        {

            Bitmap objPic, objNewPic;
            try
            {
                objPic = new Bitmap(strOldPic);
                int intHeight = (int)(((float)intWidth / (float)objPic.Width) * (float)objPic.Height);
                objNewPic = new Bitmap(objPic, intWidth, intHeight);

                saveImg(objNewPic, strNewPic);
            }
            catch (Exception exp) { throw exp; }
            finally
            {
                objPic = null;
                objNewPic = null;
            }
        }


        /// <summary>
        /// 按比例缩小图片，自动计算宽度
        /// </summary>
        /// <param name="strOldPic">源图文件名(包括路径)</param>
        /// <param name="strNewPic">缩小后保存为文件名(包括路径)</param>
        /// <param name="intHeight">缩小至高度</param>
        public void SmallPicH(string strOldPic, string strNewPic, int intHeight)
        {

            Bitmap objPic, objNewPic;
            try
            {
                objPic = new Bitmap(strOldPic);
                int intWidth = (int)(((float)intHeight / (float)objPic.Height) * (float)objPic.Width);
                objNewPic = new Bitmap(objPic, intWidth, intHeight);

                saveImg(objNewPic, strNewPic);
            }
            catch (Exception exp) { throw exp; }
            finally
            {
                objPic = null;
                objNewPic = null;
            }
        }

        /// <summary>
        /// 等比缩放，长和宽不能超过限制
        /// </summary>
        /// <param name="strOldPic"></param>
        /// <param name="strNewPic"></param>
        /// <param name="limitWidth"></param>
        /// <param name="limitHeight"></param>
        public void SmallPicAuto(string strOldPic, string strNewPic, int limitWidth,int limitHeight)
        {
            Image image = Image.FromFile(strOldPic);

            //小于要求图，不做缩放
            if (image.Width < limitWidth && image.Height < limitHeight)
                image.Save(strNewPic);

            //原图高或宽小于指定值，缩小要求
            if (image.Width < limitWidth)
                limitWidth = image.Width;            
            if (image.Height < limitHeight)
                limitHeight = image.Height;

            double rw = (double)image.Width / (double)limitWidth;
            double rh = (double)image.Height / (double)limitHeight;

            //缩放比例
            double scale_rate = rw;
            if (scale_rate < rh)
                scale_rate = rh;

            limitWidth = (int)(image.Width / scale_rate);
            limitHeight = (int)(image.Height / scale_rate);


            Bitmap b = new Bitmap(image, limitWidth, limitHeight);

            try
            {              
                saveImg(b, strNewPic);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message + ex.StackTrace);
            }
            finally
            {
                image.Dispose();
                b.Dispose();
            }            
        }


        private void saveImg(Bitmap objNewPic, string strNewPic)
        {
            ImageCodecInfo ici = GetCodecInfo("image/" + GetFormat(strNewPic).ToString().ToLower());

            EncoderParameters encoderParams = new EncoderParameters();

            EncoderParameter encoderParam = new EncoderParameter(Encoder.Quality, (long)100);
            encoderParams.Param[0] = encoderParam;

            objNewPic.Save(strNewPic, ici, encoderParams);

            encoderParam.Dispose();
            encoderParams.Dispose();
        }

        /// <summary>
        /// 从图片中切割一切儿出来
        /// </summary>
        /// <param name="strOldPic"></param>
        /// <param name="strNewPic"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        public void SmallPicCut(string strOldPic,string strNewPic,int width,int height)
        {
            Image image = Image.FromFile(strOldPic);

            //小于要求图，不做缩放
            if (image.Width < width && image.Height < height)
                image.Save(strNewPic);

            //原图高或宽小于指定值，缩小要求
            if (image.Width < width)
                width = image.Width;
            
            if(image.Height < height)
                height = image.Height;

            double rw = (double)image.Width / (double)width;
            double rh = (double)image.Height / (double)height;

            //缩放比例
            double scale_rate = rw;
            if (scale_rate > rh)
                scale_rate = rh;

            int srcx, srcy;

            if(rw>rh)
            {
                double tmp = image.Width / scale_rate;
                srcx = (int)(((int)tmp - width) / 2 * scale_rate);
                srcy = 0;
            }
            else if(rw<rh)
            {
                double tmp = image.Height / scale_rate;
                srcx = 0;
                srcy = (int)(((int)tmp - height) / 2 * scale_rate);
            }
            else
            {
                srcx = 0;
                srcy = 0;
            }

            Bitmap b = new Bitmap(width, height);

            try
            {
                Graphics g = Graphics.FromImage(b);
                g.InterpolationMode = InterpolationMode.High;
                g.SmoothingMode = SmoothingMode.HighQuality;

                //清除整个绘图面并以透明背景色填充
                g.Clear(Color.Transparent);

                g.DrawImage(image, new Rectangle(0, 0, width, height),
                    new Rectangle(srcx, srcy, image.Width - srcx * 2, image.Height - srcy * 2), 
                    GraphicsUnit.Pixel);

                saveImg(b, strNewPic);
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message + ex.StackTrace);
            }
            finally
            {
                image.Dispose();
                b.Dispose();
            }
        }

        /// <summary>
        /// 获取图像编码解码器的所有相关信息
        /// </summary>
        /// <param name="mimeType">包含编码解码器的多用途网际邮件扩充协议 (MIME) 类型的字符串</param>
        /// <returns>返回图像编码解码器的所有相关信息</returns>
        private static ImageCodecInfo GetCodecInfo(string mimeType)
        {
            ImageCodecInfo[] CodecInfo = ImageCodecInfo.GetImageEncoders();
            foreach (ImageCodecInfo ici in CodecInfo)
            {
                if (ici.MimeType == mimeType) return ici;
            }
            return null;
        }

        /// <summary>
        /// 得到图片格式
        /// </summary>
        /// <param name="name">文件名称</param>
        /// <returns></returns>
        public static ImageFormat GetFormat(string name)
        {
            string ext = name.Substring(name.LastIndexOf(".") + 1);
            switch (ext.ToLower())
            {
                case "jpg":
                case "jpeg":
                    return ImageFormat.Jpeg;
                case "bmp":
                    return ImageFormat.Bmp;
                case "png":
                    return ImageFormat.Png;
                case "gif":
                    return ImageFormat.Gif;
                default:
                    return ImageFormat.Jpeg;
            }
        }
    }
}
